﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace Obsidian.Components
{
    public class ComponentCollection : List<Component>
    {
        public new void Add(Component component)
        {
            base.Add(component);
        }


        // Should return true if the collection already contains the type
        public bool ContainsType(Type type)
        {
            foreach (var item in this)
            {
                if (item.GetType() == type)
                {
                    return true;
                }
            }
            return false;
        }

        // Should return all of a certain type
        public List<Component> GetAllOfType(Type type)
        {
            List<Component> list = new List<Component>();

            foreach (var item in this)
            {
                if (item.GetType() == type)
                {
                    list.Add(item);
                }
            }
            return list;
        }

        // Should return all of a certain base type
        public List<Component> GetAllOfBaseType(Type type)
        {
            List<Component> list = new List<Component>();

            foreach (var item in this)
            {
                if (item.GetType().BaseType == type)
                {
                    list.Add(item);
                }
            }
            return list;
        }

        /// <summary>
        /// Returns the component of Type type if the game object has one attached, null if it doesn't.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public Component GetComponent(Type type)
        {
            foreach (var component in this)
            {
                if (component.GetType() == type)
                {
                    return component;
                }
            }

            // non found 
            return null;
        }

        /// <summary>
        /// Returns the component of Type type if the game object has one attached, null if it doesn't.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public Component GetBaseComponent(Type type)
        {
            foreach (var component in this)
            {
                if (component.GetType().BaseType == type)
                {
                    return component;
                }
            }

            // non found 
            return null;
        }

        /// <summary>
        /// Returns the component with name type if the game object has one attached, null if it doesn't.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public Component GetComponent(string name)
        {
            foreach (var component in this)
            {
                if (component.Name == name)
                {
                    return component;
                }
            }

            // non found 
            return null;
        }

        /// <summary>
        /// Returns the component of Type type if the game object has one attached, null if it doesn't.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public Component GetComponent<T>()
        {
            foreach (var component in this)
            {
                if (component.GetType() == typeof(T))
                {
                    return component;
                }
            }

            // non found 
            return null;
        }

        /// <summary>
        /// Returns all components of Type type in the GameObject.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public Component[] GetComponents(Type type)
        {
            List<Component> components = new List<Component>();

            foreach (var component in this)
            {
                if (component.GetType() == type)
                {
                    components.Add(component);
                }
            }
            return components.ToArray();
        }

        /// <summary>
        /// Returns all components of Type type in the GameObject.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public Component[] GetComponents<T>()
        {
            List<Component> components = new List<Component>();

            foreach (var component in this)
            {
                if (component.GetType() == typeof(T))
                {
                    components.Add(component);
                }
            }
            return components.ToArray();
        }
    }
}
